package com.awesome.common.util

import android.os.Handler
import android.os.Looper
import android.os.Message

/**
 * Author: JFangZ
 * Email: janezhang1901@163.com
 * Date: 2021/5/7 9:38
 * Description:The helper for accurate countdown.
 */
class CountDownHelper(private val millisInFuture: Long, private val countDownInterval: Long) {
    var isStop = true
    var isPause = false
    private var onTickListener: ((millisUntilFinished: Long) -> Unit)? = null
    private var onFinishListener: (() -> Unit)? = null
    private var stopTimeInFuture: Long = 0

    private val handler: Handler by lazy {
        return@lazy Handler(Looper.myLooper()!!, object : Handler.Callback {
            override fun handleMessage(msg: Message): Boolean {
                synchronized(this) {
                    if (isStop || isPause) {
                        return false
                    }
                    stopTimeInFuture -= countDownInterval
                    if (stopTimeInFuture <= 0) {
                        isStop = true
                        onFinishListener?.invoke()
                    } else {
                        onTickListener?.invoke(stopTimeInFuture)
                        handler.sendMessageDelayed(handler.obtainMessage(0), countDownInterval)
                    }
                    return true
                }
            }

        })
    }

    @Synchronized
    private fun start(millisInFuture: Long) {
        isStop = false
        isPause = false
        if (millisInFuture <= 0) {
            isStop = true
            onFinishListener?.invoke()
            return
        }
        stopTimeInFuture = millisInFuture
        onTickListener?.invoke(stopTimeInFuture)
        handler.sendMessageDelayed(handler.obtainMessage(0), countDownInterval)
    }

    @Synchronized
    fun start() {
        if (!isStop) {
            return
        }
        start(millisInFuture)
    }

    @Synchronized
    fun stop() {
        isStop = true
        handler.removeMessages(0)
    }

    @Synchronized
    fun pause() {
        // Can't pause after stop.
        if (isStop) {
            return
        }
        isPause = true
        handler.removeMessages(0)
    }

    @Synchronized
    fun restart() {
        // Can't restart after stop or doesn't pause.
        if (isStop || !isPause) {
            return
        }
        start(stopTimeInFuture)
    }

    fun setOnTickListener(onTickListener: ((millisUntilFinished: Long) -> Unit)?): CountDownHelper {
        this.onTickListener = onTickListener
        return this
    }

    fun setOnFinishListener(onFinishListener: (() -> Unit)?): CountDownHelper {
        this.onFinishListener = onFinishListener
        return this
    }
}